Data Types
Inferred
An inferred data type means Go figures out the variable’s type automatically from the value you give it — you don’t have to write the type yourself.
When you use the short declaration syntax:
name := "Alice"
- You didn’t say
stringanywhere. - Go sees
"Alice"is text in quotes → infers type =string.
Why it’s possible
- Go is statically typed (types are fixed at compile time), but the compiler is smart enough to detect the type from the value.
- This only works when you assign a value immediately.
What happens if you don’t give a value?
x := // ❌ ERROR: missing value
- Go must have a value to infer the type.
- If you want an empty variable, you must use var and specify the type:
var x int
Once inferred, type is fixed
Even if Go inferred the type for you, it’s still fixed:
count := 10 // int
count = "ten" // ❌ ERROR: cannot assign string to int
Common values and the types Go infers for them when you use :=:
| Value | Inferred Type | Explanation |
|---|---|---|
42 | int | Whole number → integer type |
3.14 | float64 | Decimal number → 64-bit float |
"Hello" | string | Text in quotes → string |
true | bool | true or false → boolean |
'a' | rune | Single quotes → rune (Unicode char) |
[]int{1, 2, 3} | []int | Slice (list) of integers |
map[string]int{"a": 1} | map[string]int | Map with string keys and int values |
Example of inferred
func main() {
x := 42 // int
y := 3.14 // float64
s := "Hello" // string
b := true // bool
c := 'a' // rune
arr := []int{1,2} // slice of int
m := map[string]int{"a": 1}
fmt.Printf("%T %T %T %T %T %T %T\n", x, y, s, b, c, arr, m)
}
Primitive Data Types
1. Numbers
Integers
- Whole numbers, no decimal point.
- Two forms: signed (can be negative) and unsigned (only positive).
| Type | Size (bits) | Range Example |
|---|---|---|
int | platform-dependent (32 or 64 bits) | Large range for general use |
int8 | 8 bits | -128 to 127 |
int16 | 16 bits | -32,768 to 32,767 |
int32 | 32 bits | -2,147,483,648 to 2,147,483,647 |
int64 | 64 bits | Very large range |
uint8 | 8 bits | 0 to 255 (alias: byte) |
uint16 | 16 bits | 0 to 65,535 |
uint32 | 32 bits | 0 to 4,294,967,295 |
uint64 | 64 bits | 0 to very large |
Floating Point Numbers
- Numbers with decimals.
| Type | Size (bits) | Range / Precision |
|---|---|---|
float32 | 32 bits | ~6 decimal digits |
float64 | 64 bits | ~15 decimal digits (default) |
Complex Numbers
- Numbers with a real and imaginary part.
| Type | Example |
|---|---|
complex64 | 1 + 2i (real: float32, imaginary: float32) |
complex128 | 3 + 4i (real: float64, imaginary: float64) |
2. Text
String
- Sequence of characters inside double quotes
" ". - Immutable (cannot be changed after creation).
var name string = "Masum"
fmt.Println(name)
Rune
- Represents a single Unicode character.
- Stored as an
int32.
var letter rune = 'A'
fmt.Println(letter) // prints Unicode code point 65
Composite Data Types
1. Array
- Fixed-size list of elements of the same type.
var numbers [3]int = [3]int{1, 2, 3}
2. Slice
- Like an array, but size can change.
fruits := []string{"Apple", "Banana", "Cherry"}
3. Map
Key-value pairs (like a dictionary).
scores := map[string]int{"Alice": 90, "Bob": 85}
4. Struct
Groups different fields into one object.
type Person struct {
name string
age int
}
Interface and Special Types
- Interface: Defines behavior without implementation.
- Pointer: Stores memory address of a value.
- Nil: Zero value for pointers, maps, slices, etc.
Example of Data Types
package main
import "fmt"
func main() {
// Basic types
var age int = 25
var pi float64 = 3.14
var name string = "Alice"
var isActive bool = true
// Composite
fruits := []string{"Apple", "Banana"}
scores := map[string]int{"Bob": 80, "Eve": 95}
fmt.Println(age, pi, name, isActive)
fmt.Println("Fruits:", fruits)
fmt.Println("Scores:", scores)
}
Output:
25 3.14 Alice true
Fruits: [Apple Banana]
Scores: map[Bob:80 Eve:95]
struct
In Go, a struct is a composite data type that groups together zero or more fields (variables) under a single name. It’s similar to classes in object-oriented languages, but structs don’t have methods directly—instead, you can attach methods to them separately.
Key Features of Struct in Go
- User-defined type – lets you define your own data model.
- Collection of fields – each with a name and type.
- Zero-value initialization – all fields get a default value (e.g.,
0for int,""for string). - Pass by value – when assigning or passing, the struct gets copied (unless you use pointers).
- Supports methods – you can attach methods to structs (like OOP classes).
- Anonymous fields & embedding – allows inheritance-like behavior.
- Nested struct – struct inside another struct.
Example of Basic struct
package main
import "fmt"
// Define a struct
type Person struct {
Name string
Age int
City string
}
func main() {
// 1. Create struct with field names
p1 := Person{Name: "Masum", Age: 24, City: "Dhaka"}
// 2. Create struct without specifying field names (order matters)
p2 := Person{"Ayesha", 22, "Chittagong"}
// 3. Zero-value struct
var p3 Person // all fields empty: "" and 0
p3.Name = "Rahim"
p3.Age = 30
p3.City = "Sylhet"
fmt.Println(p1) // {Masum 24 Dhaka}
fmt.Println(p2) // {Ayesha 22 Chittagong}
fmt.Println(p3) // {Rahim 30 Sylhet}
}
Nested Structs
package main
import "fmt"
type Address struct {
City string
Street string
}
type Student struct {
Name string
Age int
Address Address // nested struct
}
func main() {
s := Student{
Name: "Masum",
Age: 24,
Address: Address{
City: "Dhaka",
Street: "Banani",
},
}
fmt.Println(s.Name, "lives in", s.Address.City)
}
Anonymous & Embedded Structs (like inheritance)
package main
import "fmt"
type Person struct {
Name string
Age int
}
// Embedded struct
type Employee struct {
Person // inherits fields of Person
EmployeeID string
}
func main() {
e := Employee{
Person: Person{Name: "Masum", Age: 24},
EmployeeID: "EMP123",
}
// Direct access (because of embedding)
fmt.Println(e.Name) // Masum
fmt.Println(e.EmployeeID) // EMP123
}